package org.javahispano.javacup.tacticas.tacticas_aceptadas.jmv;


import java.awt.Color;
import org.javahispano.javacup.modelo.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class KapriFC implements Tactica {

    Posicion alineacion1[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-31.082089552238806),
        new Posicion(11.16030534351145,-31.6044776119403),
        new Posicion(27.251908396946565,-27.94776119402985),
        new Posicion(-29.84732824427481,-26.902985074626866),
        new Posicion(27.34265734265734,12.115384615384617),
        new Posicion(-10.641221374045802,-7.052238805970149),
        new Posicion(5.944055944055944,-4.038461538461538),
        new Posicion(-26.391608391608393,31.357466063348415),
        new Posicion(-0.2595419847328244,19.067164179104477),
        new Posicion(-0.2595419847328244,35.78358208955224)
    };

    Posicion alineacion2[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-19.46564885496183,-31.6044776119403),
        new Posicion(0.2595419847328244,-31.082089552238806),
        new Posicion(19.984732824427482,-31.6044776119403),
        new Posicion(7.526717557251908,-11.753731343283583),
        new Posicion(-8.564885496183205,-11.753731343283583),
        new Posicion(-24.65648854961832,-2.3507462686567164),
        new Posicion(23.099236641221374,-2.873134328358209),
        new Posicion(-14.274809160305344,30.559701492537314),
        new Posicion(-0.7786259541984732,8.097014925373134),
        new Posicion(12.717557251908397,29.51492537313433)
    };

    Posicion alineacion3[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-31.082089552238806),
        new Posicion(11.16030534351145,-31.6044776119403),
        new Posicion(26.732824427480914,-20.111940298507463),
        new Posicion(-29.32824427480916,-21.67910447761194),
        new Posicion(0.2595419847328244,-0.26119402985074625),
        new Posicion(-18.946564885496183,-0.26119402985074625),
        new Posicion(18.946564885496183,-0.26119402985074625),
        new Posicion(-19.46564885496183,35.78358208955224),
        new Posicion(-0.2595419847328244,19.067164179104477),
        new Posicion(18.946564885496183,35.26119402985075)
    };

    Posicion alineacion4[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-31.082089552238806),
        new Posicion(11.16030534351145,-31.6044776119403),
        new Posicion(28.290076335877863,-28.470149253731343),
        new Posicion(-28.290076335877863,-28.470149253731343),
        new Posicion(11.16030534351145,-1.3059701492537314),
        new Posicion(-10.641221374045802,-0.7835820895522387),
        new Posicion(-27.251908396946565,31.6044776119403),
        new Posicion(-10.641221374045802,30.559701492537314),
        new Posicion(9.603053435114505,28.992537313432837),
        new Posicion(25.69465648854962,28.992537313432837)
    };

    Posicion alineacion5[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-35.78358208955224),
        new Posicion(12.717557251908397,-35.26119402985075),
        new Posicion(28.290076335877863,-28.470149253731343),
        new Posicion(-28.290076335877863,-28.470149253731343),
        new Posicion(14.793893129770993,-18.544776119402986),
        new Posicion(-17.389312977099234,-19.58955223880597),
        new Posicion(-23.618320610687025,-0.7835820895522387),
        new Posicion(5.969465648854961,-5.485074626865671),
        new Posicion(0.2595419847328244,-0.26119402985074625),
        new Posicion(22.580152671755727,-1.3059701492537314)
    };

    Posicion alineacion6[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-35.78358208955224),
        new Posicion(12.717557251908397,-35.26119402985075),
        new Posicion(28.290076335877863,-28.470149253731343),
        new Posicion(-28.290076335877863,-28.470149253731343),
        new Posicion(14.793893129770993,-18.544776119402986),
        new Posicion(-17.389312977099234,-19.58955223880597),
        new Posicion(-23.618320610687025,-0.7835820895522387),
        new Posicion(6.4885496183206115,-6.529850746268657),
        new Posicion(-6.4885496183206115,-6.529850746268657),
        new Posicion(22.580152671755727,-1.3059701492537314)
    };

    Posicion cornerInferiorIzq[]=new Posicion[]{
            new Posicion(0.2595419847328244,-50.41044776119403),
            new Posicion(-19.496503496503497,-51.549773755656105),
            new Posicion(-10.223776223776223,-42.76018099547511),
            new Posicion(-3.5664335664335667,-38.72171945701358),
            new Posicion(-19.25874125874126,-46.56108597285068),
            new Posicion(5.468531468531468,-41.57239819004525),
            new Posicion(-16.643356643356643,-34.44570135746606),
            new Posicion(-12.601398601398602,-13.065610859728507),
            new Posicion(1.4265734265734267,-30.407239819004527),
            new Posicion(0.0,-9.97737556561086),
            new Posicion(12.363636363636363,-38.95927601809955)
        };

        Posicion cornerInferiorDer[]=new Posicion[]{
            new Posicion(0.2595419847328244,-50.41044776119403),
            new Posicion(19.97202797202797,-51.074660633484164),
            new Posicion(-10.223776223776223,-42.76018099547511),
            new Posicion(-3.5664335664335667,-38.72171945701358),
            new Posicion(19.734265734265733,-45.61085972850679),
            new Posicion(5.468531468531468,-41.57239819004525),
            new Posicion(-16.643356643356643,-34.44570135746606),
            new Posicion(-12.601398601398602,-13.065610859728507),
            new Posicion(1.4265734265734267,-30.407239819004527),
            new Posicion(0.0,-9.97737556561086),
            new Posicion(12.363636363636363,-38.95927601809955)
        };

        Posicion cornerSuperiorDer[]=new Posicion[]{
            new Posicion(0.2595419847328244,-50.41044776119403),
            new Posicion(9.272727272727272,-30.407239819004527),
            new Posicion(-11.412587412587413,-29.457013574660635),
            new Posicion(-2.13986013986014,-29.694570135746606),
            new Posicion(-8.321678321678322,-4.98868778280543),
            new Posicion(-1.6643356643356644,7.126696832579185),
            new Posicion(1.188811188811189,27.08144796380091),
            new Posicion(-11.65034965034965,44.42307692307692),
            new Posicion(0.23776223776223776,41.334841628959275),
            new Posicion(32.33566433566433,50.59954751131222),
            new Posicion(14.74125874125874,46.08597285067873)
        };

        Posicion cornerSuperiorIzq[]=new Posicion[]{
            new Posicion(0.2595419847328244,-50.41044776119403),
            new Posicion(9.272727272727272,-30.407239819004527),
            new Posicion(-11.412587412587413,-29.457013574660635),
            new Posicion(-2.13986013986014,-29.694570135746606),
            new Posicion(-8.321678321678322,-4.98868778280543),
            new Posicion(-1.6643356643356644,7.126696832579185),
            new Posicion(1.188811188811189,27.08144796380091),
            new Posicion(-11.65034965034965,44.42307692307692),
            new Posicion(0.23776223776223776,41.334841628959275),
            new Posicion(-31.622377622377623,49.64932126696832),
            new Posicion(14.74125874125874,46.08597285067873)
        };


    class TacticaDetalleImpl implements TacticaDetalle {

        public String getNombre() {
            return "Kapri FC";
        }

        public String getPais() {
            return "España";
        }

        public String getEntrenador() {
            return "Luciano Hansenberger";
        }

        public Color getColorCamiseta() {
            return new Color(255, 204, 0);
        }

        public Color getColorPantalon() {
            return new Color(27, 97, 75);
        }

        public Color getColorFranja() {
            return new Color(255, 255, 0);
        }

        public Color getColorCalcetas() {
            return new Color(255, 255, 0);
        }

        public Color getColorPortero() {
            return new Color(37, 111, 220        );
        }

        public EstiloUniforme getEstilo() {
            return EstiloUniforme.SIN_ESTILO;
        }

        public Color getColorCamiseta2() {
            return new Color(255, 255, 255);
        }

        public Color getColorPantalon2() {
            return new Color(121, 161, 110);
        }

        public Color getColorFranja2() {
            return new Color(152, 87, 207);
        }

        public Color getColorCalcetas2() {
            return new Color(38, 83, 139);
        }

        public Color getColorPortero2() {
            return new Color(17, 40, 189        );
        }

        public EstiloUniforme getEstilo2() {
            return EstiloUniforme.FRANJA_VERTICAL;
        }

        class JugadorImpl implements JugadorDetalle {

            String nombre;
            int numero;
            Color piel, pelo;
            double velocidad, remate, presicion;
            boolean portero;
            Posicion posicion;

            public JugadorImpl(String nombre, int numero, Color piel, Color pelo,
                    double velocidad, double remate, double presicion, boolean portero) {
                this.nombre=nombre;
                this.numero=numero;
                this.piel=piel;
                this.pelo=pelo;
                this.velocidad=velocidad;
                this.remate=remate;
                this.presicion=presicion;
                this.portero=portero;
            }

            public String getNombre() {
                return nombre;
            }

            public Color getColorPiel() {
                return piel;
            }

            public Color getColorPelo() {
                return pelo;
            }

            public int getNumero() {
                return numero;
            }

            public boolean esPortero() {
                return portero;
            }

            public double getVelocidad() {
                return velocidad;
            }

            public double getRemate() {
                return remate;
            }

            public double getPresicion() {
                return presicion;
            }

        }

        public JugadorDetalle[] getJugadores() {
            return new JugadorDetalle[]{
                new JugadorImpl("Casillas", 1, new Color(255,200,150), new Color(50,0,0),1.0d,0.98d,1.0d, true),
                new JugadorImpl("Puyol", 2, new Color(255,200,150), new Color(50,0,0),1.0d,0.78d,0.75d, false),
                new JugadorImpl("Sergio Ramos", 3, new Color(255,200,150), new Color(50,0,0),1.0d,0.79d,0.79d, false),
                new JugadorImpl("Pique", 4, new Color(255,200,150), new Color(50,0,0),1.0d,0.77d,0.76d, false),
                new JugadorImpl("Busquets", 5, new Color(255,200,150), new Color(50,0,0),0.83d,0.71d,0.72d, false),
                new JugadorImpl("Iniesta", 6, new Color(255,200,150), new Color(50,0,0),0.79d,0.78d,0.67d, false),
                new JugadorImpl("Di Maria", 7, new Color(255,200,150), new Color(50,0,0),0.76d,0.64d,0.57d, false),
                new JugadorImpl("Xavi", 8, new Color(255,200,150), new Color(50,0,0),1.0d,0.5d,0.5d, false),
                new JugadorImpl("Cristiano Ronaldo", 9, new Color(255,200,150), new Color(50,0,0),1.0d,0.75d,0.65d, false),
                new JugadorImpl("Mesi", 10, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,1.0d, false),
                new JugadorImpl("Villa", 11, new Color(255,200,150), new Color(50,0,0),1.0d,1.0d,1.0d, false)
            };
        }
    }

    TacticaDetalle detalle=new TacticaDetalleImpl();
    public TacticaDetalle getDetalle() {
        return detalle;
    }

    public Posicion[] getPosicionSaca(SituacionPartido sp) {
    return alineacion5;
    }

    public Posicion[] getPosicionRecive(SituacionPartido sp) {
    return alineacion6;
    }

    private static final int porteroIndice = 0;
    private int iteracionesParaSacar = 0;
    
    public List<Comando> ejecutar(SituacionPartido sp) {
    	
    	List<Comando> result = new ArrayList<Comando>();
    	
    	cambiarAlineacion(sp, result);
    	
    	if (sp.puedenRematar().length > 0) {

			for (int jugador : sp.puedenRematar()) {

				if(jugador == porteroIndice){
					ComandoGolpearBalon golpear = new ComandoGolpearBalon(jugador, 90, 1, 40);
					result.add(golpear);
				}else if(sp.saco()){
//					//System.out.println("SACO. iteracionesParaSacar: " + iteracionesParaSacar);
					
					if(iteracionesParaSacar == Constantes.ITERACIONES_SAQUE - 10){
						int count=0;
						Random r = new Random();
						int j = -1;
						Posicion[] jugadores = sp.misJugadores();
		                while ((j = r.nextInt(jugadores.length)) == jugador && jugadores[jugador].getY()>jugadores[j].getY() && count<20){
		                    count++;
		                };
		                result.add(new ComandoGolpearBalon(jugador, jugadores[j], 3, r.nextInt(45)));
		                
		                iteracionesParaSacar = 0;
					}else if(iteracionesParaSacar > Constantes.ITERACIONES_SAQUE){
						iteracionesParaSacar = 0;
					}else{
						
						// Desplazamos a un compañero para que le pueda sacar el balón
						int[] jugadoresParaCombinar = sp.misJugadores()[jugador].indicesMasCercanos(sp.misJugadores(), 0 , jugador);
						
						if(jugadoresParaCombinar.length > 0){
							
							for(int jugadorParaCombinar : jugadoresParaCombinar){
								
								if(jugadorParaCombinar != 0 && jugadorParaCombinar != jugador){
									
									double x = 0;
									if(sp.balon().getX() < 0){
										x = sp.balon().getX() + 10;
									}else{
										x = sp.balon().getX() - 10;
									}
									
									Posicion newPosition = new Posicion(x, sp.balon().getY());
									
									ComandoIrA muevete = new ComandoIrA(jugadorParaCombinar, newPosition);
									result.add(muevete);
									
									break;
								}
								
							}
							
						}
						
					}
					
				}else if (jugador==8 || jugador==9 || jugador==10 || jugador==11) {
					Random r = new Random();
	                if (r.nextBoolean()) {
	                    result.add(new ComandoGolpearBalon(jugador, Constantes.centroArcoSup, 3, 12+r.nextInt(6)));
	                } else {
	                    if (r.nextBoolean()) {
	                    	result.add(new ComandoGolpearBalon(jugador, Constantes.posteDerArcoSup, 3, 12+r.nextInt(6)));
	                    } else {
	                    	result.add(new ComandoGolpearBalon(jugador, Constantes.posteIzqArcoSup, 3, 12+r.nextInt(6)));
	                    }
	                }
	                
	            }else if(jugador == 5 || jugador == 6) {
	                result.add(new ComandoGolpearBalon(jugador));
	                
	            }else{
	            	int count=0;
					Random r = new Random();
					int j = -1;
					Posicion[] jugadores = sp.misJugadores();
	                while ((j = r.nextInt(jugadores.length)) == jugador && jugadores[jugador].getY()>jugadores[j].getY() && count<20){
	                    count++;
	                };
	                result.add(new ComandoGolpearBalon(jugador, jugadores[j], 3, r.nextInt(45)));
	            }
			}
    	}
    	
    	
    	// Portero
		int[] recuperadores = sp.getRecuperacionBalon();
		if (recuperadores.length > 1) {
			for (int i = 1; i < 2; i++) {
				
				double[] posRecuperacion = sp.getTrayectoria(iteracionMejorParaRecuperarBalonSegunAltura(sp));
				result.add(new ComandoIrA(recuperadores[i], new Posicion(
						posRecuperacion[0], posRecuperacion[1])));
				
			}
		}
		
//		if(sp.golesPropios() == sp.golesRival() && sp.balon().distancia(sp.misJugadores()[0]) < 50){
//			
//			if (sp.puedenRematar().length > 0 && sp.puedenRematarRival().length == 0) {
//				
//				for(int jugador : sp.puedenRematar()){
//					
//					if(jugador != 0){
//						// El portero no actúa aquí
//						ComandoGolpearBalon golpear = new ComandoGolpearBalon(jugador);
//						result.add(golpear);
//						
//						ComandoIrA irA = new ComandoIrA(jugador, new Posicion(40, sp.misJugadores()[0].getY()));
//						result.add(irA);
//					}
//				}
//				
//			}
//			
//		}
		
        return result;
    }
    
    
    private boolean existeJugadorRivalCercaDeBalon(SituacionPartido sp){
    	
    	boolean result = false;

    	for(Posicion rival : sp.rivales()){
    		
    		if(rival.distancia(sp.balon()) < 10){
    			result = true;
    			break;
    		}
    	}
    	
    	return result;
    }
    
    
    private int iteracionMejorParaRecuperarBalonSegunAltura(SituacionPartido sp){
    	
    	int result = -1;
    	
    	int[] recuperadores = sp.getRecuperacionBalon();
    	if (recuperadores.length > 1) {
    		
    		int iteracionRecuperacion = recuperadores[0];
    		
    		int iteracionesMaximas = 30;
    		int cont = 0;
    		
    		while(cont < iteracionesMaximas || result != -1){
    			
    			double[] posRecuperacion = sp.getTrayectoria(iteracionRecuperacion);
    			if(posRecuperacion.length == 3 && posRecuperacion[2] <= Constantes.ALTURA_CONTROL_BALON){
    				// podemos controlar el balón por alto
    				result = iteracionRecuperacion;
    				break;
    			}else{
    				cont++;
    				iteracionRecuperacion++;
    			}
    			
    		}
    		
    		if(result == -1){
    			result = iteracionRecuperacion;
    		}
    	}
    	
    	return result;
    }
    
    /**
	 * Usa una alineacion para todos los jugadores.
	 * @param comandos
	 * @param alineacion
	 * @param sp
	 */
	private void usarAlineacion(List<Comando> comandos, Posicion[] alineacion, SituacionPartido sp){
		
		Posicion[] jugadores = sp.misJugadores();
		for (int i = 0; i < jugadores.length; i++) {
			comandos.add(new ComandoIrA(i, alineacion[i]));
		}
		
	}
    
    private void cambiarAlineacion(SituacionPartido sp, List<Comando> result){
    	if(sp.sacaRival()){
//			//System.out.println("SACA RIVAL. iteracionesParaSacar: " + iteracionesParaSacar);
			int cont = 0;
			
			
			int[] recuperadores = sp.getRecuperacionBalon();
			if (recuperadores.length > 1) {
				for (int i = 1; i < 2; i++) {
					double[] posRecuperacion = sp.getTrayectoria(recuperadores[0]);
						result.add(new ComandoIrA(recuperadores[i], new Posicion(
								posRecuperacion[0], posRecuperacion[1])));
				}
			}
			
			
			if(sp.balon().equals(Constantes.cornerInfDer)){
//				//System.out.println("SAQUE " + cont++);
				usarAlineacion(result, cornerInferiorDer, sp);
				
			}else if(sp.balon().equals(Constantes.cornerInfIzq)){
//				//System.out.println("SAQUE " + cont++);
				usarAlineacion(result, cornerInferiorIzq, sp);
				
			}else if(sp.balon().equals(Constantes.cornerSupIzq)){
//				//System.out.println("SAQUE " + cont++);
				usarAlineacion(result, cornerSuperiorIzq, sp);
				
			}else if(sp.balon().equals(Constantes.cornerSupDer)){
//				//System.out.println("SAQUE " + cont++);
				usarAlineacion(result, cornerSuperiorDer, sp);
				
			}
			
		}else if(sp.saco()){
			//System.out.println("SACO. iteracionesParaSacar: " + iteracionesParaSacar);
			int cont = 0;
			
			iteracionesParaSacar++;
			
			int[] recuperadores = sp.getRecuperacionBalon();
			if (recuperadores.length > 1) {
				for (int i = 1; i < 2; i++) {
					double[] posRecuperacion = sp.getTrayectoria(recuperadores[0]);
						result.add(new ComandoIrA(recuperadores[i], new Posicion(
								posRecuperacion[0], posRecuperacion[1])));
				}
			}
			
			if(sp.balon().equals(Constantes.cornerInfDer)){
//				//System.out.println("SAQUE " + cont++);
				usarAlineacion(result, cornerInferiorDer, sp);
				
			}else if(sp.balon().equals(Constantes.cornerInfIzq)){
//				//System.out.println("SAQUE " + cont++);
				usarAlineacion(result, cornerInferiorIzq, sp);
				
			}else if(sp.balon().equals(Constantes.cornerSupIzq)){
//				//System.out.println("SAQUE " + cont++);
				usarAlineacion(result, cornerSuperiorIzq, sp);
				
			}else if(sp.balon().equals(Constantes.cornerSupDer)){
//				//System.out.println("SAQUE " + cont++);
				usarAlineacion(result, cornerSuperiorDer, sp);
				
			}
		}else{
			usarAlineacion(result, alineacion1, sp);
		}
    }
}